/**
 * Created by Administrator on 2025/5/7.
 * */
#include "AIE2E.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

BaseObject *createAIE2E() {
    return new AIE2E();
}

void destroyAIE2E(BaseObject *p) {
    SAFE_DELETE(p);
}

/*__global__ void TaskKernel(char *in, char *out) {
    int tid = blockIdx.x * blockDim.x + threadIdx.x;
    out[tid] = in[tid];
}*/

AIE2E::AIE2E(){
    this->setGPUDevice(0);
    prevStep = -1;
    // 订阅数据源主题Topic
    sub = zmq::socket_t(context, zmq::socket_type::sub);
    sub.connect(topicAddr.c_str());
    sub.set(zmq::sockopt::subscribe, topicName);
    // 接收ZMQ控制命令
    rep_socket = zmq::socket_t(context, ZMQ_REP);
    rep_socket.bind(rep_address);
    std::thread thd(&AIE2E::zmqRepServe, this);
    thd.detach();
}

AIE2E::~AIE2E() {
}

void AIE2E::zmqRepServe() {
    // 处理CFAR控制命令
    zmq::message_t command;
    try {
        rep_socket.recv(command, zmq::recv_flags::none);
    } catch (const zmq::error_t& e) {
        std::cerr << "ZMQ error: " << e.what() << std::endl;
    }
    int cmdId;
    memcpy(&cmdId, command.data(), sizeof(int));
    if (1 == cmdId) {
        std::cout << "AIE2EInfer::AIE2E：开始模型升级" << std::endl;
    }
    // 发送确认
    int ackVal = 200;
    zmq::message_t ack(sizeof(int));
    memcpy(ack.data(), &ackVal, sizeof(int));
    rep_socket.send(ack, zmq::send_flags::none);
}

void AIE2E::onIssueStreamedCudaOperations(buffer_table_t *input, buffer_table_t *output, cudaStream_t stream) {
    int step;
    zmq::message_t msgTopicName;
    zmq::message_t msgData;
    if (!sub.recv(msgTopicName, zmq::recv_flags::none)) {
        std::cerr << "Subscribe: Failed to receive topic name" << std::endl;
    }
    std::string topicName_(static_cast<char*>(msgTopicName.data()), msgTopicName.size());
    if (!sub.recv(msgData, zmq::recv_flags::none)) {
        std::cerr << "Subscribe: Failed to receive data" << std::endl;
    }
    memcpy(&step, msgData.data(), sizeof(float));
    if (prevStep == step) {
        return ;
    }
    prevStep = step;
    // 根据全局aiE2EState确定相应的操作
    int aiE2EState = GlobalParameters::shareInstance()->get_parameter_aiE2EState(dynamic_cast<TaskModule*>(this));
    // 初始训练模型升级
    if (aiE2EState==static_cast<int>(AIE2EStateEnum::Ini_Model_Notify)) {
        std::cout << "AIE2EInfer::AIE2E: 开始升级模型..." << std::endl;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Ini_Model_Updating);
    }
    if (static_cast<int>(AIE2EStateEnum::Ini_Model_Updating)==aiE2EState && step==STEP4_2) {
        std::cout << "AIE2EInfer::AIE2E: 升级成功" << std::endl;
        precision = P1;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Ini_Model_Updated);
        // 更新全局状态aiE2EMonitorState，使其开始工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *aiE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *aiE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Runing);
    }
    // 传统算法辅助模型升级
    if (aiE2EState==static_cast<int>(AIE2EStateEnum::Tat_Model_Notify)) {
        std::cout << "AIE2EInfer::AIE2E: 开始升级模型（传统算法辅助）..." << std::endl;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Tat_Model_Updating);
    }
    if (static_cast<int>(AIE2EStateEnum::Tat_Model_Updating)==aiE2EState && step==STEP9) {
        std::cout << "AIE2EInfer::AIE2E: 升级成功（传统算法辅助）" << std::endl;
        precision = P2;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Tat_Model_Updated);
    }
    // 虚拟真值升级
    if (aiE2EState==static_cast<int>(AIE2EStateEnum::Vtt_Model_Notify)) {
        std::cout << "AIE2EInfer::AIE2E: 开始升级模型（虚拟真值）..." << std::endl;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Vtt_Model_Updating);
    }
    if (static_cast<int>(AIE2EStateEnum::Vtt_Model_Updating)==aiE2EState && step==STEP12) {
        std::cout << "AIE2EInfer::AIE2E: 升级成功（虚拟真值）" << std::endl;
        precision = P3;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Vtt_Model_Updated);
        // 通知AIE2E更新全局状态aiE2EMonitorState，使其开始工作
        auto aiE2EMonitorStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EMonitorState");
        int *pAIE2EMonitorState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EMonitorStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EMonitorState = static_cast<int>(AIE2EMonitorStateEnum::Sst_Notify);
    }
    // 自监督学习升级
    if (aiE2EState==static_cast<int>(AIE2EStateEnum::Sst_Model_Notify)) {
        std::cout << "AIE2EInfer::AIE2E: 开始升级模型（自监督学习）..." << std::endl;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Sst_Model_Updating);
    }
    if (static_cast<int>(AIE2EStateEnum::Sst_Model_Updating)==aiE2EState && step==STEP15) {
        std::cout << "AIE2EInfer::AIE2E: 升级成功（自监督学习）" << std::endl;
        precision = P4;
        auto aiE2EStateHolder = GlobalParameters::shareInstance()->findParameter("aiE2EState");
        int *pAIE2EState = static_cast<int*>(GlobalParameters::shareInstance()->getValue(aiE2EStateHolder, dynamic_cast<TaskModule*>(this)));
        *pAIE2EState = static_cast<int>(AIE2EStateEnum::Sst_Model_Updated);
    }
    std::cout << "AIE2EInfer：端到端系统识别精度：" << precision*100 << "%; 识别目标数：1个" << std::endl;
}
